
/* Includes ------------------------------------------------------------------*/
#include "bmp280.h"
#include "i2c-eiri.h"
#include "usart.h"
#include "string.h"

uint32_t atmoPressure = 0;
uint32_t RealAMOPressure = 0;
uint8_t deviceID = 0;
uint8_t mode = normalMode;
int32_t t_fine = 0;
static bmp280_calib_data bmp280_calib;

uint8_t I2C_BMP280_ReadData(uint16_t Addr, uint8_t Reg, uint8_t* data, uint8_t size)
{    
    while(HAL_I2C_Master_Transmit(&hi2c1, Addr<<1, &Reg, 1, 100) != HAL_OK)
    {                
        if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
        {
            I2C1_ClearBusyFlag();
            SET_BMP280_NormalMode();
            DEBUG_Printf("ERROR:%d\r\n",HAL_I2C_GetError(&hi2c1));
            DEBUG_Printf("i2c1.instance->sr2:%x\r\n",hi2c1.Instance->SR2);
            DEBUG_Printf("read transmit anknowledgement failure\r\n");
        }
    }
    
    if(HAL_I2C_Master_Receive(&hi2c1, (Addr<<1)|0x01, data, size, 100) != HAL_OK)
    {
        if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
        {
            I2C1_ClearBusyFlag();
            SET_BMP280_NormalMode();
            DEBUG_Printf("ERROR:%d\r\n",HAL_I2C_GetError(&hi2c1));
            DEBUG_Printf("i2c1.instance->sr2:%x\r\n",hi2c1.Instance->SR2);
            DEBUG_Printf("read receive anknowledgement failure\r\n");
        }        
    }         
    return 0;
}

uint8_t I2C_BMP280_WriteData(uint16_t Addr, uint8_t Reg, uint8_t* data, uint8_t size)
{       
    uint8_t pData[size+1];
    pData[0] = Reg;
    memcpy(&pData[1], data, size);  
    
    while(HAL_I2C_Master_Transmit(&hi2c1, Addr<<1, pData, size + 1, 500) != HAL_OK)
    {                
        //if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF )
        {
            I2C1_ClearBusyFlag();
            SET_BMP280_NormalMode();
            DEBUG_Printf("ERROR:%d\r\n",HAL_I2C_GetError(&hi2c1));
            DEBUG_Printf("i2c1.instance->sr2:%x\r\n",hi2c1.Instance->SR2);
            DEBUG_Printf("write transmit anknowledgement failure\r\n");
            //HAL_Delay(1000);
        }        
    }      
    return 0;
}

uint8_t SET_BMP280_NormalMode(void)
{
    //mode = mode |0x20;
    I2C_BMP280_WriteData(BMP280_ADDRESS, BMP280_REGISTER_CONTROL, &mode, 1);
    return 1;
}

uint8_t GET_BMP280_ID(void)
{   
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_CHIPID, &deviceID, 1); 
    return deviceID;
}

void GET_BMP280_Coefficients(void)
{
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_T1, (uint8_t*)&bmp280_calib.dig_T1, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_T2, (uint8_t*)&bmp280_calib.dig_T2, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_T3, (uint8_t*)&bmp280_calib.dig_T3, 2);
    
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P1, (uint8_t*)&bmp280_calib.dig_P1, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P2, (uint8_t*)&bmp280_calib.dig_P2, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P3, (uint8_t*)&bmp280_calib.dig_P3, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P4, (uint8_t*)&bmp280_calib.dig_P4, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P5, (uint8_t*)&bmp280_calib.dig_P5, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P6, (uint8_t*)&bmp280_calib.dig_P6, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P7, (uint8_t*)&bmp280_calib.dig_P7, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P8, (uint8_t*)&bmp280_calib.dig_P8, 2);
    I2C_BMP280_ReadData(BMP280_ADDRESS, BMP280_REGISTER_DIG_P9, (uint8_t*)&bmp280_calib.dig_P9, 2);    
}

double GET_BMP280_Temperature(void)
{
  double var1 = 0, var2 = 0;
  
  int32_t adc_T = 0, temp = 0;
    
  I2C_BMP280_ReadData( BMP280_ADDRESS, BMP280_REGISTER_TEMPDATA, (uint8_t*)&temp, 3);      
  adc_T |= (temp & 0xFF)<<12;
  adc_T |= ((temp & 0xFF00)>>8)<<4;
  adc_T |= ((temp & 0xF00000)>>20);
  
  GET_BMP280_Coefficients();

  var1  = (((double)adc_T)/16384.0 - ((double)bmp280_calib.dig_T1)/1024.0)*((double)bmp280_calib.dig_T2);    
    
  var2  = (((double)adc_T)/131072.0 - ((double)bmp280_calib.dig_T1)/8192.0)*(((double)adc_T)/131072.0 -((double)bmp280_calib.dig_T1)/8192.0)*((double)bmp280_calib.dig_T3);
    
  t_fine = (int32_t)(var1 + var2);
  /* comment by llb 
  DEBUG_Printf("adc_T:0x%x, temp:0x%x\r\n", adc_T, temp);
  DEBUG_Printf("var1:%f\r\n", var1);
  DEBUG_Printf("var2:%f\r\n", var2);
  DEBUG_Printf("bmp280_calib.dig_T1:%d\r\n", bmp280_calib.dig_T1);
  DEBUG_Printf("bmp280_calib.dig_T2:%d\r\n", bmp280_calib.dig_T2);
  DEBUG_Printf("bmp280_calib.dig_T3:%d\r\n", bmp280_calib.dig_T3);
  DEBUG_Printf("temperature:%0.1f \r\n",(double)t_fine/5120.0);
  */
  return (double)t_fine/5120.0;
}

/**************************************************************************/
/*!

*/
/**************************************************************************/
double GET_BMP280_Pressure(void)
{
  int64_t var1, var2, p;
  int32_t adc_P = 0, temp = 0;
  
  GET_BMP280_Temperature();  
    
  I2C_BMP280_ReadData( BMP280_ADDRESS, BMP280_REGISTER_PRESSUREDATA, (uint8_t*)&temp, 3);     
  adc_P |= (temp & 0xFF)<<12;
  adc_P |= ((temp & 0xFF00)>>8)<<4;
  adc_P |= ((temp & 0xF00000)>>20);

  var1 = ((int64_t)t_fine) - 128000;
  var2 = var1 * var1 * (int64_t)bmp280_calib.dig_P6;
  var2 = var2 + ((var1*(int64_t)bmp280_calib.dig_P5)<<17);
  var2 = var2 + (((int64_t)bmp280_calib.dig_P4)<<35);
  var1 = ((var1 * var1 * (int64_t)bmp280_calib.dig_P3)>>8) +
    ((var1 * (int64_t)bmp280_calib.dig_P2)<<12);
  var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bmp280_calib.dig_P1)>>33;
  
  if (var1 == 0) {
    return 0;  // avoid exception caused by division by zero
  }
  p = 1048576 - adc_P;
  p = (((p<<31) - var2)*3125) / var1;
  var1 = (((int64_t)bmp280_calib.dig_P9) * (p>>13) * (p>>13)) >> 25;
  var2 = (((int64_t)bmp280_calib.dig_P8) * p) >> 19;

  p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280_calib.dig_P7)<<4);
  return (double)p/256;    
    
//  var1 = ((double)t_fine)/2.0 - 64000.0;
//  var2 = var1 * var1 * ((double)bmp280_calib.dig_P6)/32768.0;
//  var2 = var2 + var1*((double)bmp280_calib.dig_P5)*2.0;
//  var2 = var2/4.0 + (((double)bmp280_calib.dig_P4)*65536.0);
//  var1 = (((double)bmp280_calib.dig_P3)*var1*var1/524288.0 + ((double)bmp280_calib.dig_P2)*var1)/524288.0;
//  var1 = (1.0 + var1/32768.0)*((double)bmp280_calib.dig_P1);
//  
//  p = 1048576.0 - (double)adc_P;
//  p = (p-(var2/4096.0))*6250.0/var1;
//  var1 = ((double)bmp280_calib.dig_P9) * p * p /2147483648.0;
//  var2 = (((double)bmp280_calib.dig_P8) * p)/32768.0;

//  p = p + (var1 + var2 + ((double)bmp280_calib.dig_P7))/16.0;
//  return (double)p/256;
}
